
package com.smartfit;

import android.util.Log;

class AccelValueFileData
{
	private static final String RTTI = "AccelValueFileData";
	
	// 데이터 타입
	// 각도
	static final int DATA_TYPE_ANGLE = 0;
	// 속도
	static final int DATA_TYPE_VELOCITY = 1;
	// 거리
	static final int DATA_TYPE_DISTANCE = 2;
	// 축
	static final int DATA_X = 0;
	static final int DATA_Y = 1;
	static final int DATA_Z = 2;
	
	// 패턴
	
	static final int PATTERN_SAME = -1;
	static final int PATTERN_UP = 0;
	static final int PATTERN_DOWN = 1;
	static final int PATTERN_STAY = 2;
	
	static final int PATTERN_STABLE = 0;
	static final int PATTERN_FLEXIBLE = 1;
	
	// 데이터에 중력값을 포함할 지 유무
	boolean m_bIsContainedGravity;
	// 데이터 시간 간격
	int m_iTimeInterval;
	// 데이터 갯수
	int m_iNumDatum;
	// 각도
	AccelValue m_Angle = new AccelValue();
	// 속도
	AccelValue m_Velocity = new AccelValue();
	// 거리
	AccelValue m_Distance = new AccelValue();
	// 거리의 합
	Axis3f m_SumDistance = new Axis3f();
	
	AccelValueFileData()
	{
		Clear();
	}
	
	public void Clear()
	{
		m_bIsContainedGravity = true;
		m_iTimeInterval = 0;
		m_iNumDatum = 0;
		// 각도
		m_Angle.Clear();
		// 속도
		m_Velocity.Clear();
		// 거리
		m_Distance.Clear();
		// 거리의 합
		m_SumDistance.Clear();
	}
	
	public int GetNumData( int iDataType )
	{
		switch ( iDataType )
		{
			case DATA_TYPE_ANGLE:
				
				return m_Angle.GetNumData();
	
			case DATA_TYPE_VELOCITY:
				
				return m_Velocity.GetNumData();
	
			case DATA_TYPE_DISTANCE:
				
				return m_Distance.GetNumData();
	
			default:
				
				Log.d( RTTI , "Invalid data type" );
				
		}
		
		return 0;
	}
	
	public boolean IsContainedGravity()
	{
		return m_bIsContainedGravity;
	}

	public int GetTimeInterval()
	{
		return m_iTimeInterval;
	}
	
	public Axis3f GetDistance()
	{
		return m_SumDistance;
	}
	
	public void SetDistance( double x , double y , double z )
	{
		m_SumDistance.x = x;
		m_SumDistance.y = y;
		m_SumDistance.z = z;
	}
	
	public double Get( int iDataType , int iAxisType , int iIndex )
	{
		AccelValue data = null;
		
		switch ( iDataType )
		{
			case DATA_TYPE_ANGLE:
				
				data = m_Angle;
				
				break;
	
			case DATA_TYPE_VELOCITY:
				
				data = m_Velocity;
				
				break;
	
			case DATA_TYPE_DISTANCE:
				
				data = m_Distance;
				
				break;

			default:
				
				Log.d( RTTI , "Invalid data type" );
				
				return Double.MAX_VALUE;
		}
		
		switch ( iAxisType )
		{
			case DATA_X:
				
				return data.accelValueXs.get( iIndex );
			
			case DATA_Y:
				
				return data.accelValueYs.get( iIndex );
			
			case DATA_Z:
				
				return data.accelValueZs.get( iIndex );
				
			default:
				
				Log.d( RTTI , "Invalid axis type" );
		}
		
		return Double.MAX_VALUE;
	}

	public void Set( int iDataType , double x , double y , double z )
	{
		AccelValue data = null;
		
		switch ( iDataType )
		{
			case DATA_TYPE_ANGLE:
				
				// 각도
				data = m_Angle;
				// 각도  저장 갯수
				m_iNumDatum++;
				
				break;
	
			case DATA_TYPE_VELOCITY:
				
				// 속도
				data = m_Velocity;
				
				break;
	
			case DATA_TYPE_DISTANCE:
				
				// 거리
				data = m_Distance;
				
				// 거리합
				m_SumDistance.x += x;
				m_SumDistance.y += y;
				m_SumDistance.z += z;				
				
				break;

			default:
				
				Log.d( RTTI , "Invalid data type" );
				
				return;
		}
		
		data.accelValueXs.add( x );
		data.accelValueYs.add( y );
		data.accelValueZs.add( z );
	}
	
	public void Copy( AccelValueFileData s )
	{
		m_iTimeInterval = s.GetTimeInterval();
		m_iNumDatum = s.GetNumData( DATA_TYPE_ANGLE );
		
		m_Angle.Copy( s.m_Angle );
		m_Velocity.Copy( s.m_Velocity );
		m_Distance.Copy( s.m_Distance );
		
		m_SumDistance.Copy( s.m_SumDistance );
	}
	
	public int Analyze_1( int iAxis )
	{
		int iNumDatum = GetNumData( DATA_TYPE_ANGLE );
		
		if ( iNumDatum <= 1 )
		{
			return PATTERN_SAME;
		}
		
		int iPrevDataIndex = ( iNumDatum - 2 );
		int iCurrDataIndex = ( iNumDatum - 1 );

		double p = Get( AccelValueFileData.DATA_TYPE_ANGLE , iAxis , iPrevDataIndex );
		double c = Get( AccelValueFileData.DATA_TYPE_ANGLE , iAxis , iCurrDataIndex );
		
		double diff = ( c - p );

		if ( diff > 0 )
		{
			return PATTERN_UP;
		}
		else if ( diff < 0 )
		{
			return PATTERN_DOWN;
		}
		
		return PATTERN_SAME;
	}
	
	public int Analyze( int iAxis , int iNumCompareFrameForPattern )
	{
		int iNumCompareSize = iNumCompareFrameForPattern + 1;
		int iNumDatum = GetNumData( DATA_TYPE_ANGLE );
		
		if ( iNumDatum <= 1 )
		{
			return PATTERN_SAME;
		}
		
		if ( iNumCompareSize > iNumDatum )
		{
			iNumCompareSize = iNumDatum;
		}
		
		double [] piPattern = new double[iNumCompareSize];
		
		for ( int i = 0 ; i < iNumCompareSize ; i++ )
		{
			piPattern[i] = 0;
		}

		for ( int i = ( iNumDatum -1 ) ; i > ( iNumDatum - iNumCompareSize ) ; i-- )
		{
			double p = Get( AccelValueFileData.DATA_TYPE_ANGLE , iAxis , i - 1 );
			double c = Get( AccelValueFileData.DATA_TYPE_ANGLE , iAxis , i );
			
			int iIndex = ( i - ( iNumDatum - iNumCompareSize ) );
			
			double diff = ( c - p );
			
			int iCompare = 0;
			
			if ( diff > 0 )
			{
				piPattern[iIndex] = 1;
			}
			else if ( diff < 0 )
			{
				piPattern[iIndex] = -1;
			}
			else
			{
				piPattern[iIndex] = 0;
			}
		}
		
		// 제일 마지막(현재 패턴)이 0 이면 변경없음
		if ( piPattern[( iNumCompareSize - 1 )] == 0 )
		{
			return 0;
		}
		
		// 중간에 0 이 있는 경우 다음꺼로 대체
		for ( int i = iNumCompareSize - 1  ; i > 1 ; i-- )
		{
			if ( piPattern[i] == 0 )
			{
				piPattern[i] = piPattern[( i + 1 )];
			}
		}
		
		// 다 더하면 ?
		
		int iResult = 0;

		for ( int i = 0 ; i < iNumCompareSize ; i++ )
		{
			iResult += piPattern[i];
		}
		
		// 더하면 0이 나올 수 없음
		
		if ( iResult > 0 )
		{
			return PATTERN_UP;
		}
		else if ( iResult < 0 )
		{
			return PATTERN_DOWN;
		}

		return PATTERN_SAME;
	}
}
